﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Text;

namespace MyBasicLib.Utilities
{
    /// <summary>
    /// 调用wcf
    /// </summary>
    /// <typeparam name="TChannel"></typeparam>
    public static class ServiceInvoker<TChannel>
    {
        static ChannelFactory<TChannel> factoryInstence;
        private static object syncHelper = new object();
        static ChannelFactory<TChannel> GetChannelFactoryByConfigurationName(string endpointConfigurationName)
        {
            if (factoryInstence == null)
                lock (syncHelper)
                    if (factoryInstence == null)
                        return factoryInstence = new ChannelFactory<TChannel>(endpointConfigurationName);
            return factoryInstence;
        }
        //static ChannelFactory<TChannel> GetChannelFactory(string configurationName)
        //{
        //    if (factoryInstence == null)
        //        lock (syncHelper)
        //            if (factoryInstence == null)
        //                return factoryInstence = new ChannelFactory<TChannel>(new CustomBinding(configurationName));
        //    return factoryInstence;
        //}
        public static void Invoke(string endpointConfigurationName, Action<TChannel> action)
        {
            Invoke(endpointConfigurationName, p => { action(p); return 0; });
        }
        public static TResult Invoke<TResult>(string endpointConfigurationName, Func<TChannel, TResult> function)
        {
            var proxy = GetChannelFactoryByConfigurationName(endpointConfigurationName).CreateChannel();

            ICommunicationObject channel = proxy as ICommunicationObject;
            if (null == channel)
            {
                throw new ArgumentException("The proxy is not a valid channel implementing the ICommunicationObject interface", "proxy");
            }
            try
            {
                return function(proxy);
            }
            catch (TimeoutException)
            {
                channel.Abort();
                throw;
            }
            catch (CommunicationException)
            {
                channel.Abort();
                throw;


            }
            finally
            {
                channel.Close();
            }
        }
        //public static TResult Invoke<TResult>(Func<TChannel, TResult> function)
        //{
        //    var proxy = GetChannelFactory("defaultBinding").CreateChannel(new EndpointAddress("http://localhost:2001/UserService.svc"));

        //    ICommunicationObject channel = proxy as ICommunicationObject;
        //    if (null == channel)
        //    {
        //        throw new ArgumentException("The proxy is not a valid channel implementing the ICommunicationObject interface", "proxy");
        //    }
        //    try
        //    {
        //        return function(proxy);
        //    }
        //    catch (TimeoutException)
        //    {
        //        channel.Abort();
        //        throw;
        //    }
        //    catch (CommunicationException)
        //    {
        //        channel.Abort();
        //        throw;
        //    }
        //    finally
        //    {
        //        channel.Close();
        //    }
        //}

    }
}
